package com.ror.java.se.inet.tcp;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Demo03TcpFileMultithreadServer {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(10000);
        File localDestDir = new File("assets"
                + File.separator + "inet"
                + File.separator + "tcp"
                + File.separator + "server-dir");

        //线程池
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                3, 12, 60, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );

        while (true) {
            //默认文件名（采用UUID生成唯一文件名）
            String filename = UUID.randomUUID().toString().replace("-", "") + ".jpg";
            Socket socket = ss.accept();

            //一旦accept到一个客户端，就往线程池提交一条线程
            //一个客户端会话对应一条线程
            pool.submit(() -> {
                try {
                    receive(socket, localDestDir, filename);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            });
        }

//        ss.close(); //服务器不关闭
    }

    private static void receive(Socket socket, File localDestDir, String filename) throws IOException {
        //接收文件
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(localDestDir, filename)));
        byte[] buf = new byte[1024];
        int len;
        while ((len = bis.read(buf)) != -1) {
            bos.write(buf, 0, len);
        }
        //把缓冲区剩下的数据继续写出
        bos.flush();

        //向客户端发送反馈
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bw.write("(服务器已成功接收文件)");
        bw.newLine();
        bw.flush();

        socket.close();
    }
}
